home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / libc / atof.c < prev    next >
C/C++ Source or Header  |  1989-03-22  |  6KB  |  246 lines

  1. /* 
  2.  * atof.c --
  3.  *
  4.  *    Source code for the "atof" library procedure.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/atof.c,v 1.2 89/03/22 00:46:56 rab Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22.  
  23. #ifndef TRUE
  24. #define TRUE 1
  25. #define FALSE 0
  26. #endif
  27.  
  28. static int maxExponent = 511;    /* Largest possible base 10 exponent.  Any
  29.                  * exponent larger than this will already
  30.                  * produce underflow or overflow, so there's
  31.                  * no need to worry about additional digits.
  32.                  */
  33. static double powersOf10[] = {    /* Table giving binary powers of 10.  Entry */
  34.     10.,            /* is 10^2^i.  Used to convert decimal */
  35.     100.,            /* exponents into floating-point numbers. */
  36.     1.0e4,
  37.     1.0e8,
  38.     1.0e16,
  39.     1.0e32,
  40.     1.0e64,
  41.     1.0e128,
  42.     1.0e256
  43. };
  44.  
  45. /*
  46.  *----------------------------------------------------------------------
  47.  *
  48.  * atof --
  49.  *
  50.  *    This procedure converts a floating-point number from an ASCII
  51.  *    decimal representation to internal double-precision format.
  52.  *
  53.  * Results:
  54.  *    The return value is the floating-point equivalent of string.
  55.  *    If a terminating character is found before any floating-point
  56.  *    digits, then zero is returned.
  57.  *
  58.  * Side effects:
  59.  *    None.
  60.  *
  61.  *----------------------------------------------------------------------
  62.  */
  63.  
  64. double
  65. atof(string)
  66.     char *string;        /* A decimal ASCII floating-point number,
  67.                  * optionally preceded by white space.
  68.                  * Must have form "-I.FE-X", where I is the
  69.                  * integer part of the mantissa, F is the
  70.                  * fractional part of the mantissa, and X
  71.                  * is the exponent.  Either of the signs
  72.                  * may be "+", "-", or omitted.  Either I
  73.                  * or F may be omitted, or both.  The decimal
  74.                  * point isn't necessary unless F is present.
  75.                  * The "E" may actually be an "e".  E and X
  76.                  * may both be omitted (but not just one).
  77.                  */
  78. {
  79.     int sign, expSign = FALSE;
  80.     double fraction, dblExp, *d;
  81.     register char *p, c;
  82.     int exp = 0;        /* Exponent read from "EX" field. */
  83.     int fracExp = 0;        /* Exponent that derives from the fractional
  84.                  * part.  Under normal circumstatnces, it is
  85.                  * the negative of the number of digits in F.
  86.                  * However, if I is very long, the last digits
  87.                  * of I get dropped (otherwise a long I with a
  88.                  * large negative exponent could cause an
  89.                  * unnecessary overflow on I alone).  In this
  90.                  * case, fracExp is incremented one for each
  91.                  * dropped digit.
  92.                  */
  93.     int mantSize;        /* Number of digits in mantissa. */
  94.     int decPt;            /* Number of mantissa digits BEFORE decimal
  95.                  * point.
  96.                  */
  97.     char *pExp;            /* Temporarily holds location of exponent
  98.                  * in string.
  99.                  */
  100.  
  101.     /*
  102.      * Strip off leading blanks and check for a sign.
  103.      */
  104.  
  105.     p = string;
  106.     while (isspace(*p)) {
  107.     p += 1;
  108.     }
  109.     if (*p == '-') {
  110.     sign =     TRUE;
  111.     p += 1;
  112.     } else {
  113.     if (*p == '+') {
  114.         p += 1;
  115.     }
  116.     sign = FALSE;
  117.     }
  118.  
  119.     /*
  120.      * Count the number of digits in the mantissa (including the decimal
  121.      * point), and also locate the decimal point.
  122.      */
  123.  
  124.     decPt = -1;
  125.     for (mantSize = 0; ; mantSize += 1)
  126.     {
  127.     c = *p;
  128.     if (!isdigit(c)) {
  129.         if ((c != '.') || (decPt >= 0)) {
  130.         break;
  131.         }
  132.         decPt = mantSize;
  133.     }
  134.     p += 1;
  135.     }
  136.  
  137.     /*
  138.      * Now suck up the digits in the mantissa.  Use two integers to
  139.      * collect 9 digits each (this is faster than using floating-point).
  140.      * If the mantissa has more than 18 digits, ignore the extras, since
  141.      * they can't affect the value anyway.
  142.      */
  143.     
  144.     pExp  = p;
  145.     p -= mantSize;
  146.     if (decPt < 0) {
  147.     decPt = mantSize;
  148.     } else {
  149.     mantSize -= 1;            /* One of the digits was the point. */
  150.     }
  151.     if (mantSize > 18) {
  152.     fracExp = decPt - 18;
  153.     mantSize = 18;
  154.     } else {
  155.     fracExp = decPt - mantSize;
  156.     }
  157.     if (mantSize == 0) {
  158.     return 0.0;
  159.     } else {
  160.     int frac1, frac2;
  161.     frac1 = 0;
  162.     for ( ; mantSize > 9; mantSize -= 1)
  163.     {
  164.         c = *p;
  165.         p += 1;
  166.         if (c == '.') {
  167.         c = *p;
  168.         p += 1;
  169.         }
  170.         frac1 = 10*frac1 + (c - '0');
  171.     }
  172.     frac2 = 0;
  173.     for (; mantSize > 0; mantSize -= 1)
  174.     {
  175.         c = *p;
  176.         p += 1;
  177.         if (c == '.') {
  178.         c = *p;
  179.         p += 1;
  180.         }
  181.         frac2 = 10*frac2 + (c - '0');
  182.     }
  183.     fraction = (1.0e9 * frac1) + frac2;
  184.     }
  185.  
  186.     /*
  187.      * Skim off the exponent.
  188.      */
  189.  
  190.     p = pExp;
  191.     if ((*p == 'E') || (*p == 'e')) {
  192.     p += 1;
  193.     if (*p == '-') {
  194.         expSign = TRUE;
  195.         p += 1;
  196.     } else {
  197.         if (*p == '+') {
  198.         p += 1;
  199.         }
  200.         expSign = FALSE;
  201.     }
  202.     while (isdigit(*p)) {
  203.         exp = exp * 10 + (*p - '0');
  204.         p += 1;
  205.     }
  206.     }
  207.     if (expSign) {
  208.     exp = fracExp - exp;
  209.     } else {
  210.     exp = fracExp + exp;
  211.     }
  212.  
  213.     /*
  214.      * Generate a floating-point number that represents the exponent.
  215.      * Do this by processing the exponent one bit at a time to combine
  216.      * many powers of 2 of 10. Then combine the exponent with the
  217.      * fraction.
  218.      */
  219.  
  220.     if (exp < 0) {
  221.     expSign = TRUE;
  222.     exp = -exp;
  223.     } else {
  224.     expSign = FALSE;
  225.     }
  226.     if (exp > maxExponent) {
  227.     exp = maxExponent;
  228.     }
  229.     dblExp = 1.0;
  230.     for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
  231.     if (exp & 01) {
  232.         dblExp *= *d;
  233.     }
  234.     }
  235.     if (expSign) {
  236.     fraction /= dblExp;
  237.     } else {
  238.     fraction *= dblExp;
  239.     }
  240.  
  241.     if (sign) {
  242.     return -fraction;
  243.     }
  244.     return fraction;
  245. }
  246.